#include "MapManager.h"
#include <QDebug>
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
#include <QRandomGenerator>

MapManager::MapManager(QObject *parent)
    : QObject(parent)
{

}

void MapManager::registerFixedMap(const QString &name,
                                  const QString &tilesetPath,
                                  const QVector<QVector<int> > &mapDate)
{
    MapData map;
    map.name = name;

    if (!map.tileset.load(tilesetPath)){
        qWarning() << "Failed to load tileset: " << tilesetPath;
        return;
    }

    map.tileData = mapDate;
    map.height = mapDate.size();
    if (map.height > 0)
    {
        map.width = mapDate[0].size();
    }

    findSpecialPoint(map);

    maps.insert(map.name, map);
    qDebug() << "Registered fixed map: " << name;
}

void MapManager::registerMap(const QString &name, const QString &tilesetPath, int width, int height)
{
    MapData map;
    map.name = name;
    if (!map.tileset.load(tilesetPath)) {
        qWarning() << "Failed to load tileset: " << tilesetPath;
        return;
    }
    map.width = width;
    map.height = height;

    // 生成地图数据
    generateMapData(map);

    maps.insert(name, map);
}

void MapManager::loadMap(const QString &name, QGraphicsScene *scene)
{
    if (!maps.contains(name)) { // 检查地图是否包含
        qWarning() << "Map not found:" << name;
        return;
    }

    scene->clear();
    currentMap = name;
    const MapData &map = maps[name]; // 取出地图

    // 渲染地图
    for (int y = 0; y < map.height; ++y) {
        for (int x = 0; x < map.width; ++x) {
            int tileIndex = map.tileData[y][x];

            // 计算瓦片在 瓦片集(tileset) 中的位置
            int tilesPerRow = map.tileset.width() / tileSize;
            int tileX = (tileIndex % tilesPerRow) * tileSize;
            int tileY = (tileIndex / tilesPerRow) * tileSize;

            QGraphicsPixmapItem *tile = new QGraphicsPixmapItem(
                map.tileset.copy(tileX, tileY, tileSize, tileSize));

            tile->setPos(x * tileSize, y * tileSize);
            scene->addItem(tile);
        }
    }

    qDebug() << "Loaded map:" << name << "PointOfBirth at:" << map.pointBrith;
}

bool MapManager::isInGrassArea(const QPointF &position) const
{
    if (!maps.contains(currentMap))
        return false;

    const MapData &map = maps[currentMap];
    const int tileSize = 32;

    int x = position.x() / tileSize;
    int y = position.y() / tileSize;

    if (x >= 0 && x < map.width && y >= 0 && y < map.height) {
        // 假设草地瓦片的索引为5
        return map.tileData[y][x] == TerrainType::GRASS;
    }
    return false;
}

void MapManager::SwitchMap(const QString &name, QGraphicsScene *scene)
{
    // if(name==currentMap)
    //     return;
    if (!maps.contains(name)) { // 检查地图是否包含
        qWarning() << "Map not found:" << name;
        return;
    }
    currentMap = name;
    const MapData &map = maps[name]; // 取出地图
    // 渲染地图
    for (int y = 0; y < map.height; ++y) {
        for (int x = 0; x < map.width; ++x) {
            int tileIndex = map.tileData[y][x];

            // 计算瓦片在 瓦片集(tileset) 中的位置
            int tilesPerRow = map.tileset.width() / tileSize;
            int tileX = (tileIndex % tilesPerRow) * tileSize;
            int tileY = (tileIndex / tilesPerRow) * tileSize;

            QGraphicsPixmapItem *tile = new QGraphicsPixmapItem(
                map.tileset.copy(tileX, tileY, tileSize, tileSize));

            tile->setPos(x * tileSize, y * tileSize);
            scene->addItem(tile);
        }
    }

    qDebug() << "Loaded map:" << name << "PointOfBirth at:" << map.pointBrith;
}


void MapManager::findSpecialPoint(MapData &map)
{
    map.pointBrith = QPoint(1, map.height - 2);
    // 在预定义地图中查找特殊点
    for (int y = 0; y < map.height; ++y) {
        for (int x = 0; x < map.width; ++x) {
            if (map.tileData[y][x] == TerrainType::POINT_BIRTH)
                map.pointBrith = QPoint(x, y);
        }
    }
}

void MapManager::generateMapData(MapData &map)
{
    map.tileData.resize(map.height);

    for (int y = 0; y < map.height; ++y) {
        map.tileData[y].resize(map.width);
        for (int x = 0; x < map.width; ++x) {
            // 边缘是墙壁，中间是地面
            if (x == 0 || x == map.width - 1 || y == 0 || y == map.height - 1) {
                map.tileData[y][x] = TerrainType::WALL; // 墙壁
            } else {
                map.tileData[y][x] = TerrainType::GROUND; // 地面
            }
        }
    }

    // 1. 添加主要道路系统（连接地图关键点）
    // 水平主干道
    int mainRoadY = map.height / 2;
    for (int x = 5; x < map.width - 5; ++x) {
        map.tileData[mainRoadY][x] = TerrainType::PATH;
        map.tileData[mainRoadY + 1][x] = TerrainType::PATH;
    }

    // 垂直主干道
    int mainRoadX = map.width / 3;
    for (int y = 5; y < map.height - 5; ++y) {
        map.tileData[y][mainRoadX] = TerrainType::PATH;
        map.tileData[y][mainRoadX + 1] = TerrainType::PATH;
    }

    // 2. 添加草地（集群式分布，更符合现实）
    const int grassClusters = 8; // 草地集群数量
    for (int i = 0; i < grassClusters; ++i) {
        int centerX = 3 + QRandomGenerator::global()->bounded(map.width - 6);
        int centerY = 3 + QRandomGenerator::global()->bounded(map.height - 6);
        int radius = 2 + QRandomGenerator::global()->bounded(3); // 集群半径

        for (int y = centerY - radius; y <= centerY + radius; y++) {
            for (int x = centerX - radius; x <= centerX + radius; x++) {
                if (x <= 0 || x >= map.width - 1 || y <= 0 || y >= map.height - 1)
                    continue;
                if (map.tileData[y][x] == TerrainType::GROUND) {
                    float distX = std::abs(x - centerX);
                    float distY = std::abs(y - centerY);
                    float distance = std::sqrt(distX * distX + distY * distY);
                    float normalizedDistance = std::min(distance, static_cast<float>(radius));
                    float probability = 0.7f * (1.0f - normalizedDistance / radius);

                    if (QRandomGenerator::global()->bounded(100) < probability * 100) {
                        map.tileData[y][x] = TerrainType::GRASS;
                    }
                }
            }
        }
    }

    // 3. 添加水域
    int riverY = map.height / 3;
    for (int x = 5; x < map.width - 5; ++x) {
        int width = (x % 10 < 5) ? 2 : 3;
        for (int w = 0; w < width; w++) {
            if (riverY + w < map.height - 1) {
                if (map.tileData[riverY + w][x] == TerrainType::GROUND)
                    map.tileData[riverY + w][x] = TerrainType::WATER;
            }
        }
    }

    //4.设置出生点
    int pointBrithX = map.width / 3;
    int pointBrithY = map.height / 2;
    map.tileData[pointBrithY][pointBrithX] = TerrainType::POINT_BIRTH;
    map.pointBrith = QPoint(pointBrithX, pointBrithY);
}
